#include <unistd.h>
#include <sys/types.h>       /* basic system data types */
#include <sys/socket.h>      /* basic socket definitions */
#include <netinet/in.h>      /* sockaddr_in{} and other Internet defns */
#include <arpa/inet.h>       /* inet(3) functions */
#include <netdb.h> 		  /*gethostbyname function */
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h> 
#include <linux/types.h>
#include <sys/stat.h>
#include <time.h>
#include <sys/select.h>
#include <termios.h>
#include <sys/reboot.h>

 #include "pub.h"
#include "p_lib.h"
#include "socket_base.h"
 #include "access_auth.h"  
#include "xm_client.h"
/*====================================================
ACCESS AUTHENTICATE PART
======================================================*/
int AccessAuth_Info_PickUp(char *Src, AccessAuth_Def *Dst)
{
	char *p_temp = NULL;
	int i;
	unsigned char DatLen = 0;
	
	p_temp = strstr(Src, "MCC:");
	if(p_temp == NULL) 
		return -1;

	p_temp += strlen("MCC:");
	i = atoi(p_temp);
	Dst->MCC = i;
	
	p_temp = strstr(Src, "MNC:");
	if(p_temp == NULL) 
		return -2;

	p_temp += strlen("MNC:");
	i = atoi(p_temp);
	Dst->MNC = i;
	
	p_temp = strstr(Src, "CID:");
	if(p_temp == NULL) 
		return -3;

	p_temp += strlen("CID:");
	i = atoi(p_temp);
	Dst->CID = i;
	
	p_temp = strstr(Src, "LAC:");
	if(p_temp == NULL) 
		return -3;

	p_temp += strlen("LAC:");
	i = atoi(p_temp);
	Dst->LAC = i;
	
	return 0;
}

int AccessAuth_info_pack(AccessAuth_Def *Src, unsigned char * Dst)
{
	TD_ComProtocl_SendFrame_t *p_dst = (TD_ComProtocl_SendFrame_t *)Dst;
	p_dst->Cmd_TAG = TAG_ACCESS_AUTH;

	memcpy(p_dst->Frame_Data, Src, sizeof(AccessAuth_Def));
	p_dst->FrameSize = sizeof(AccessAuth_Def);

	return (2 + p_dst->FrameSize);
}

int AccessAuth_Result_ANL(TD_ComProtocl_RecvFrame_t *Src, AccessAuth_Result_t *Dst, int len)//modify by lk 20150205
{	
	int Ret = 0;
	int i = 0;
	int length = sizeof(TD_Result_t);//add by lk 20151021
	unsigned char ucTmp;
	unsigned char illegal_IMSI1[9]={0,0,0,0,0,0,0,0,0};
	unsigned char illegal_IMSI2[9]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
	TD_ComProtocl_RecvFrame_t *p_AA_Result = Src;

	if(TAG_RESULT_ACCESS_AUTH != p_AA_Result->Cmd_TAG)
	{
		DBUG( "AccessAuth_Result_ANL:TAG error: TAG=%02x\n", p_AA_Result->Cmd_TAG);
		return 1;//ywy modified 20150208
	}

	if(AA_RESULT_STATE_SUCCESS != p_AA_Result->Result)
	{
		Dst->ErrCode = p_AA_Result->Frame_Data[0];
		DBUG( "Access Auth faild ErroCode=%d\n", Dst->ErrCode);

		if(Dst->ErrCode == IpChange)
		{
			return 3;
		}
		else
			return 2;//ywy modified 20150208
	}

	Dst->ErrCode = LoginSuccess;//ywy add 2016.03.23 indicate that log in success
	memcpy((char *)(&(SysCtl.AA_Result.AA_OK)), (char *)(p_AA_Result->Frame_Data), length);//cpy data to sysctl

	if(len > (4 + length))//add by lk 20151021
	{
		memcpy(&SysCtl.IMEI, (char *)(p_AA_Result->Frame_Data + sizeof(TD_Result_t)), 8);	
		DBUG( "The vIMEI is %lld\n", SysCtl.IMEI);
	}

	if((!memcmp(Dst->AA_OK.imsi, illegal_IMSI1, IMSI_LEN))||(!memcmp(Dst->AA_OK.imsi, illegal_IMSI2, IMSI_LEN)))
	{
		DBUG( "illegal imsi got from server\n");
		return 2;
	}
		
	DBUG(
		"Speed:%d,Threshold:%d,minutes_Remain:%d,data_Remain:%d,simFileUpdate:%d,DataClr:%d,vusimActive:%d,ExtendFlag:0x%02x,LocalRoamSwitch:%d, unused0:%d,unused1:%d,unused2:%d,unused3:%d\n", 
		SysCtl.AA_Result.AA_OK.dataSpeed, 
		SysCtl.AA_Result.AA_OK.threshold_data,
		SysCtl.AA_Result.AA_OK.minute_Remain,
		SysCtl.AA_Result.AA_OK.byteRemain,
		SysCtl.AA_Result.AA_OK.SimFileUpdateFlag,
		SysCtl.AA_Result.AA_OK.Data_Clr_Flag,
		SysCtl.AA_Result.AA_OK.Vusim_Active_Flag,
		(int)(SysCtl.AA_Result.AA_OK.Unused[0]),
		(int)(SysCtl.AA_Result.AA_OK.Unused[1]),
		SysCtl.AA_Result.AA_OK.reserve[0],
		SysCtl.AA_Result.AA_OK.reserve[1],
		SysCtl.AA_Result.AA_OK.reserve[2],
		SysCtl.AA_Result.AA_OK.reserve[3]
		);

	return 0;
}

int Access_Auth_Info_Recv_Error_Print(int Error_Code)
{
	switch(Error_Code)
	{
		case ERR_SELECT:
			DBUG("Access auth info recv error->ERR_SELECT:%d\n",Error_Code);
			break;
			
		case ERR_IOCTL:
			DBUG("Access auth info recv error->ERR_IOCTL:%d\n",Error_Code);
			break;
			
		case ERR_RECV:
			DBUG("Access auth info recv error->ERR_RECV:%d\n",Error_Code);
			break;
			
		case ERR_TIME_OUT:
			DBUG("Access auth info recv error->ERR_TIME_OUT:%d\n",Error_Code);
			break;
			
		default:
			DBUG("Access auth info recv error->ERR_UNKNOW:%d\n",Error_Code);
			break;
	}
	
	return 0;
}

//add by lk 20150518
int TCP_AccessAuth_Main(int socketfd, AccessAuth_Def *Src, TD_ComProtocl_RecvFrame_t *Dst, int *len)
{
	int SendLen = 0;
	int cnt = 0;
	int Ret = 0;
	unsigned char SendBuf[256];
	if(socketfd < 0 )
		return ACCESS_AUTH_FAIL_SEND_ERRO;

	/*variables initial*/
	memset(SendBuf, 0, sizeof(SendBuf));
	
	/*MSG package*/
	SendLen = AccessAuth_info_pack(Src, SendBuf);
	
	/*Send AA MSG*/
	cnt = TCP_SendMessage(socketfd, SendBuf, SendLen);
	if(cnt != SendLen)
	{
		DBUG( "Access auth info send error\n");
		return ACCESS_AUTH_FAIL_SEND_ERRO;
	}

	/*Recv AA result*/
	cnt = TCP_RecvMessage(socketfd, (unsigned char *)(Dst), 0, MSG_WAITALL, RequestTimeOut);
	if(cnt <= 0)
	{
		Access_Auth_Info_Recv_Error_Print(cnt);//add yyh 150907
		Ret = ACCESS_AUTH_FAIL_RECV_ERRO;
	}	
	else  
	{
		*len = cnt;//add by lk 20151021
		Ret = ACCESS_AUTH_FINISH;
	}
	
	return Ret;
}
